<?php
namespace app\admin\model;

use app\admin\enum\ScopeEnum;
use think\model\concern\SoftDelete;
use app\admin\model\{BaseModel, SystemRoleAdmin};
use app\Exception\EmptyException;
use app\services\TokenService;
use think\facade\Db;
use app\services\RedisService;

class SystemAdmin extends BaseModel
{
    use SoftDelete;
    protected $deleteTime = 'delete_time';

    protected $hidden = ['pid', 'rid'];

    public function getIsShowAttr($value)
    {
        $status = [0 => '禁用', 1 => '正常'];
        return $status[$value];
    }

    public function roleAdmin()
    {
        return $this->belongsToMany('SystemRole', 'SystemRoleAdmin', 'role_id', 'admin_id');
    }

    public static function checkLogin($data)
    {
        $user = new self;
        $userInfo = $user->where('username', $data['username'])->findOrEmpty();

        if($userInfo->isEmpty())
            throw new EmptyException(['status' => 302, 'errorMsg' => '用户不存在', 'errorCode' => 20001]);

        if(hash("sha256", $data['password']) != $userInfo['password'])
            throw new EmptyException(['status' => 302, 'errorMsg' => '密码错误', 'errorCode' => 20002]);

        if(!$userInfo['is_show'])
            throw new EmptyException(['status' => 302, 'errorMsg' => '此用户已被禁用！请联系管理员', 'errorCode' => 20003]);

        if($userInfo['is_delete'])
            throw new EmptyException(['status' => 302, 'errorMsg' => '此用户已被删除！请联系管理员', 'errorCode' => 20003]);

        $token = TokenService::grantToken($userInfo);
        $userInfo->login_time = date("Y-m-d H:i:s", time());
        $userInfo->save();
        unset($userInfo->password);

        return [
            'userInfo' => $userInfo,
            'token' => $token
        ];
    }

    public static function systemUpdate($data)
    {
        $token = self::grantToken();

        $redis = new RedisService();
        $userCacheVal = $redis->get($token);

        if(hash("sha256", $data['oldPassWord']) != $userCacheVal['password'])
            throw new EmptyException(['status' => 302, 'errorMsg' => '原密码错误', 'errorCode' => 20002]);
        
        if($data['newPassWord'] != $data['newPaw'])
            throw new EmptyException(['status' => 302, 'errorMsg' => '两次输入不一致', 'errorCode' => 20003]);

        if(hash("sha256", $data['newPaw']) == $userCacheVal['password'])
            throw new EmptyException(['status' => 302, 'errorMsg' => '新旧密码一致，无需修改', 'errorCode' => 20004]);

        $redis->set($token, '', 1);
        $userInfo = self::find($userCacheVal['id']);
        $userInfo->password = hash("sha256", $data['newPaw']);
        
        return $userInfo->save();
    }

    public static function adminCreate($data)
    {
        Db::startTrans();
        try {
            if(hash("sha256", $data['password']) != hash("sha256", $data['pass']))
                throw new EmptyException(['status' => 302, 'errorMsg' => '两次输入不一致', 'errorCode' => 20003]);

            $data['password'] = hash("sha256", $data['password']);

            
            $role_id = $data['rid'];

            $user = self::getByUsername($data['username']);
            if($user) throw new EmptyException(['status' => 302, 'errorMsg' => '用户已存在', 'errorCode' => 20005]);

            $model = new self;
            $data['pid'] = self::tokenToUid();
            $data['scope'] = self::tokenToScope() == ScopeEnum::Super ? ScopeEnum::Admin : ScopeEnum::User;
            $model->save($data); 

            $role['admin_id'] = $model->id;
            $role['role_id'] = $role_id;
            
            $systemRoleAdmin = new SystemRoleAdmin();
            $systemRoleAdmin->save($role);

            Db::commit();

            return true;
        } catch (\Throwable $th) {
            Db::rollback();
            throw $th;
        }
    }

    public static function adminUpdate($data)
    {
        Db::startTrans();
        try {
            $systemRoleAdmin = new SystemRoleAdmin();
            $role_id = $data['rid'];

            $user = self::getByUsername($data['username']);
            $model = $user;
            $model->save($data); 

            $systemRoleAdmin::where('admin_id', '=', $user['id'])->update(['role_id' => $role_id]);

            Db::commit();

            return true;
        } catch (\Throwable $th) {
            Db::rollback();
            throw $th;
        }
    }

    public static function adminList($param)
    {
        $model = new self;

        switch($param['state']){
            case 1:
                $model = $model->where('is_show', '=', 1);
                break;
            case 2:
                $model = $model->where('is_show', '=', 0);
                break;
            case 3:
                $model = $model->onlyTrashed();
                break;  
            default:
                $model = $model->withTrashed();
                break;   
        }

        if($param['search'] && $param['search'] != 'null'){
            $search = trim($param['search']);
            $model = $model->where('username|name', 'LIKE', "%{$search}%");
        } 

        $model = $model->with(['roleAdmin' => function($query) {
            $query->getQuery()->field('system_role.role_name');
        }])->page($param['page'], $param['pageSize'])->order('id desc');

        $scope = self::tokenToScope();
        if($scope == ScopeEnum::Super){ 
            $list = $model->select();
        }else{
            $uid = self::tokenToUid();
            $list = $model->where('id|pid', $uid)->select();
        }  

        $total = $list->count();

        return [
            'bage' => self::createBage($list),
            'list' => $list,
            'total' => $total
        ];
    }

    public static function createBage($data)
    {
        $enable = $disable = $del = 0;
        foreach($data as $item){
            $item['is_show'] == "正常" ? $enable ++ : $disable ++;
            if($item['delete_time']) $del ++;
        }

        return [
            [
                'name' => '全部', 
                'unit' => '个',
                'number' => $data->count()
            ],
            [
                'name' => '开启', 
                'unit' => '个',
                'number' => $enable
            ],
            [
                'name' => '禁用', 
                'unit' => '个',
                'number' => $disable
            ],
            [
                'name' => '删除', 
                'unit' => '个',
                'number' => $del
            ]
        ];
    }

    public static function updateState($id)
    { 
        $data = self::onlyTrashed()->find($id);
        if($data)
            return $data->restore();
        else
            return self::destroy($id);
    }

    public static function loginOut()
    {
        $token = self::grantToken();
        $redis = new RedisService();
        return $redis->set($token, '', 1);
    }
}